﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MacomberMapSystem.Common.Database;
using System.IO;

namespace MacomberMapSystem.Common.CIM.Direct
{
    /// <summary>
    /// This class holds information on a direct element
    /// </summary>
    public class CIM_DirectElement: CIM_Element
    {
        #region Variable declarations
        /// <summary>Our CIM model</summary>
        public new CIM_DirectModel CIM;
       
       
        /// <summary>Our collection of incoming links</summary>
        public List<int> _InLinks=new List<int>(10);

        /// <summary>Our collection of outgoing links</summary>
        public List<int> _OutLinks=new List<int>(10);

        /// <summary>Our collection of incoming links</summary>
        public override CIM_Link[] InLinks
        {
            get
            {
                CIM_DirectLink[] Out = new CIM_DirectLink[_InLinks.Count];
                for (int a = 0; a < _InLinks.Count; a++)
                    Out[a] = new CIM_DirectLink(CIM.Elements[_InLinks[a]]);
                return Out;
            }
        }

        /// <summary>Our collection of outgoing links</summary>
        public override CIM_Link[] OutLinks
        {
            get
            {

                CIM_DirectLink[] Out = new CIM_DirectLink[_OutLinks.Count];
                for (int a = 0; a < _OutLinks.Count; a++)
                    Out[a] = new CIM_DirectLink(CIM.Elements[_OutLinks[a]] as CIM_DirectElement);
                return Out;
            }
        }

        /// <summary>Links in either direction</summary>
        public override CIM_Link[] Links
        {
            get
            {
                CIM_DirectLink[] Out = new CIM_DirectLink[_InLinks.Count + _OutLinks.Count];
                for (int a = 0; a < _InLinks.Count; a++)
                    Out[a] = new CIM_DirectLink(CIM.Elements[_InLinks[a]] as CIM_DirectElement);
                for (int a = 0; a < _OutLinks.Count; a++)
                    Out[a + _InLinks.Count] = new CIM_DirectLink(CIM.Elements[_OutLinks[a]] as CIM_DirectElement);
                return Out;
            }
        }

        /// <summary>
        /// Report the tyupe name
        /// </summary>
        public override string TypeName
        {
            get { return CIM.Types[Type]; }
            set
            {
                for (int a = 0; a < CIM.Types.Count; a++)
                    if (CIM.Types[a] == value)
                    {
                        Type = (byte)a;
                        return;
                    }
                CIM.Types.Add(value);
                Type = (byte)(CIM.Types.Count-1);                
                CIM._AttributesByType.Add(Type, new List<ushort>(10));
            }
        }
        /// <summary>
        /// Return the XML of our element
        /// </summary>
        public override string XML
        {
            get
            {
                if (Start == -1)
                    return "<UNKNOWN rdf:ID=\"" + this.rdfID.ToString() + "\">\n</UNKNOWN>";
                else
                    using (FileStream fS = new FileStream(CIM.CIMFileName, FileMode.Open, FileAccess.Read, FileShare.Read, this.Length))
                    {
                        fS.Seek(this.Start, SeekOrigin.Begin);
                        Byte[] inB = new byte[this.Length];
                        fS.Read(inB, 0, inB.Length);
                        return Encoding.UTF8.GetString(inB);
                    }
            }
        }

        /*
        /// <summary>
        /// Report the attributes for our item
        /// </summary>
        public override Dictionary<string, string> Attributes
        {
            get
            {
                Dictionary<String, String> OutDic = new Dictionary<string, string>();
                String InnerXml = this.XML;
                OutDic.Add("Type", InnerXml.Substring(1, InnerXml.IndexOf(' ') - 1));
                int CurPos = 1;
                while ((CurPos = InnerXml.IndexOf('<', CurPos) + 1) != 0)
                {
                    String AttrName = InnerXml.Substring(CurPos, InnerXml.IndexOf('>', CurPos) - CurPos);
                    if (AttrName.Contains(" "))
                    {
                        String Val = AttrName.Substring(AttrName.IndexOf('=') + 2);
                        Val = Val.Substring(0, Val.Length - 2);
                        AttrName = AttrName.Substring(0, AttrName.IndexOf(' '));
                        if (!OutDic.ContainsKey(AttrName))
                            OutDic.Add(AttrName, Val);
                        else
                        {
                            int TryNum = 1;
                            while (OutDic.ContainsKey(AttrName + TryNum.ToString()))
                                TryNum++;
                            OutDic.Add(AttrName + TryNum.ToString(), Val);
                        }

                    }
                    else if (AttrName[0] != '/')
                    {
                        String Val = InnerXml.Substring(InnerXml.IndexOf('>', CurPos) + 1);
                        Val = Val.Substring(0, Val.IndexOf('<'));
                        if (OutDic.ContainsKey(AttrName))
                        {
                            int a = 1;
                            while (OutDic.ContainsKey(AttrName + " (" + a + ")"))
                                a++;
                            OutDic.Add(AttrName + " (" + a + ")", Val);
                        }
                        else
                            OutDic.Add(AttrName, Val);
                    }
                }
                //Also, add in the attribute for type
                return OutDic;
            }
        }
        */


        #endregion

        #region Initialization
        /// <summary>
        /// Initialize a new CIM direct element
        /// </summary>
        /// <param name="ParentModel"></param>
        public CIM_DirectElement(CIM_DirectModel ParentModel)
            : base(ParentModel)
        {
            CIM = ParentModel;
            base.CIM = ParentModel;
        }
        #endregion
    }
}
